package cn.wolfcode.business.service.impl;

import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import cn.wolfcode.common.constant.BusinessConstants;
import cn.wolfcode.common.exception.ServiceException;
import cn.wolfcode.common.utils.CarUtils;
import cn.wolfcode.common.utils.DateUtils;
import cn.wolfcode.common.utils.PhoneUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.wolfcode.business.mapper.BusAppointmentMapper;
import cn.wolfcode.business.domain.BusAppointment;
import cn.wolfcode.business.service.IBusAppointmentService;
import org.springframework.util.Assert;

/**
 * 养修信息预约Service业务层处理
 * 
 * @author zhangyf
 * @date 2023-04-11
 */
@Service
public class BusAppointmentServiceImpl implements IBusAppointmentService 
{
    @Autowired
    private BusAppointmentMapper busAppointmentMapper;

    /**
     * 查询养修信息预约
     * 
     * @param id 养修信息预约主键
     * @return 养修信息预约
     */
    @Override
    public BusAppointment selectBusAppointmentById(Long id)
    {
        return busAppointmentMapper.selectBusAppointmentById(id);
    }

    /**
     * 查询养修信息预约列表
     * 
     * @param busAppointment 养修信息预约
     * @return 养修信息预约
     */
    @Override
    public List<BusAppointment> selectBusAppointmentList(BusAppointment busAppointment)
    {
        return busAppointmentMapper.selectBusAppointmentList(busAppointment);
    }

    /**
     * 新增养修信息预约
     * 
     * @param busAppointment 养修信息预约
     * @return 结果
     */
    @Override
    public int insertBusAppointment(BusAppointment busAppointment)
    {
        // 1、预约的话,相同手机号,一天只能下五次预约单,避免恶意下单,刷爆系统
        /*
            用redis来存储用户的手机号，key：当前时间:手机号码   value：预约次数
         */

        // 校验参数
        // 校验手机号码格式
        Assert.state(PhoneUtils.isPhoneNumber(busAppointment.getCustomerPhone()),"手机号码格式错误");

        // 校验车牌号码格式
        Assert.state(CarUtils.isLicensePlate(busAppointment.getLicensePlate()),"车牌号码格式错误");
        // 校验预约时间（用@Future来做）
         /*// 这段代码不用写，我们用@Future来做
    Date appointmentTime = busAppointment.getAppointmentTime();
        Date now = new Date();
        if(appointmentTime.before(now)){
            throw new RuntimeException("预约时间不能是过去");
        }*/

        busAppointment.setCreateTime(DateUtils.getNowDate());
        // 虽然说数据库中已经设置了status的默认值，但是我们不要太过依赖数据库中的默认值，假如别人电脑的数据库表没设置默认值，那岂不是GG了。所以我们自己设置一下
        // 设置状态为预约中
        busAppointment.setStatus(BusinessConstants.APPOINTMENT_STATUS_PENDING);
        return busAppointmentMapper.insertBusAppointment(busAppointment);
    }

    /**
     * 修改养修信息预约
     * 
     * @param busAppointment 养修信息预约
     * @return 结果
     */
    @Override
    public int updateBusAppointment(BusAppointment busAppointment)
    {
        Assert.state(PhoneUtils.isPhoneNumber(busAppointment.getCustomerPhone()),"手机号码格式错误");
        Assert.state(CarUtils.isLicensePlate(busAppointment.getLicensePlate()),"车牌号码格式错误");
        // 从数据库查询被修改的预约单
        BusAppointment originBusAppointment = busAppointmentMapper.selectBusAppointmentById(busAppointment.getId());
        Assert.notNull(originBusAppointment,"非法参数");

        int status = originBusAppointment.getStatus();
        Assert.state(status == BusinessConstants.APPOINTMENT_STATUS_PENDING
        || status == BusinessConstants.APPOINTMENT_STATUS_ARRIVED,"只有预约中或者到店才可以编辑");
        return busAppointmentMapper.updateBusAppointment(busAppointment);
    }

    /**
     * 批量删除养修信息预约
     * 
     * @param ids 需要删除的养修信息预约主键
     * @return 结果
     */
    @Override
    public int deleteBusAppointmentByIds(Long[] ids)
    {
        return busAppointmentMapper.deleteBusAppointmentByIds(ids);
    }

    /**
     * 删除养修信息预约信息
     * 
     * @param id 养修信息预约主键
     * @return 结果
     */
    @Override
    public int deleteBusAppointmentById(Long id)
    {

        /*
          // 在设计表的时候，应该有一个列，记录收货地址是哪个用户的
          // 这样的数据是不是有归属性
          // 假设给普通用户做删除收货地址功能，要注意什么？（若没有设计好，可能会导致数据泄露，可能导致数据丢失，平行越权）
        解决方法：
        传参数，传就是被删除收货地址id值，千万不要传用户id过来
        在操作这个功能是不是要登录，在这个删除收货地址方法就可以获取用户id
        根据收货地址id到数据库查询收货地址，获取这个收货地址的用户id

        */

        return busAppointmentMapper.deleteBusAppointmentById(id);
    }

    @Override
    public int cancelBusAppointmentById(Long id) {
        Assert.notNull(id,"非法参数");
        BusAppointment busAppointment = busAppointmentMapper.selectBusAppointmentById(id);
        Assert.notNull(busAppointment,"非法参数");
        int status = busAppointment.getStatus();
        Assert.state(status == BusinessConstants.APPOINTMENT_STATUS_PENDING
                || status == BusinessConstants.APPOINTMENT_STATUS_ARRIVED,"只有预约中或者到店才可以取消");
        busAppointment.setStatus(BusinessConstants.APPOINTMENT_STATUS_USER_CANCELED);
        return busAppointmentMapper.updateBusAppointment(busAppointment);
    }

    @Override
    public int arriveBusAppointmentById(Long id) {
        Assert.notNull(id,"非法参数");
        BusAppointment busAppointment = busAppointmentMapper.selectBusAppointmentById(id);
        Assert.notNull(busAppointment,"非法参数");
        int status = busAppointment.getStatus();
        Assert.state(status == BusinessConstants.APPOINTMENT_STATUS_PENDING,"只有预约中才可以到店");
        busAppointment.setStatus(BusinessConstants.APPOINTMENT_STATUS_ARRIVED);
        busAppointment.setActualArrivalTime(DateUtils.getNowDate());
        return busAppointmentMapper.updateBusAppointment(busAppointment);
    }
}
